// keyof 只返回 string|number|symbol|never 以及他们的子类型集合
// 'a'能赋值给string, 但返回过来 string 不能赋值个 ’a'
// A extends B ? X : Y 如果A能赋值给B，那么返回X，否则返回Y

type T = {
    [k: string]: string | number
    a: number
    b: string
    c: 1
}

// 一般使用
type T1 = {
    [k in keyof T]: T[k]
}

// 自定义的联合
type U = 'b' | 'c'
type T2 = {
    [k in U]: T[k]
}


// 断言语法
type T3 = {
    [k in U as string]: any
}

// T3 等价于 T31
type T31 = {
    [k in string]: any
}
type T32 = {
    [k: string]: any
}

// 联合成员的过滤1：extends
type keys = keyof T // 此时keys已经将 keyof T 联合合并了, 只剩下 string | number
let a1: keys = 1
let a2: keys = '1'
type U1 = 'a' | 'b' | 'c'
type T4 = { // 由于keys只剩下了 string | number, 所以什么也没有匹配到
    [k in keys as (k extends U1 ? k : never)]: T[k]
}

// 联合成员的过滤2：keyof 在 in 的右侧，结果是不会被联合合并掉的
type T9 = {
    [k in keyof T as ( // keyof 在in的右侧时，求值但不合并，所以能保留 字面的key的类型
        k extends 'c' ? k : never
    )]: T[k]
}
